package cn.pugle.oj.leetcode;

import cn.pugle.oj.catalog.DesignProblem;

import java.util.*;

/**
 * 小改, 用堆, 27 ms
 * 把last10去掉, 23 ms
 *
 * @author tzp
 * @since 2020/11/13
 */
public class LC355_2 implements DesignProblem {
    static class Twitter {
        private static class Tweet {
            public int ts;
            public int user;
            public int tweetId;

            public Tweet(int ts, int user, int tweetId) {
                this.ts = ts;
                this.user = user;
                this.tweetId = tweetId;
            }

            public int getTweetId() {
                return tweetId;
            }
        }

        HashMap<Integer, HashSet<Integer>> fansToStar = new HashMap<>();
        HashMap<Integer, LinkedList<Tweet>> starTweetBox = new HashMap<>();
        int ts = 0;

        public Twitter() {
        }

        public void postTweet(int userId, int tweetId) {
            Tweet tweet = new Tweet(ts, userId, tweetId);
            starTweetBox.compute(userId, (key, oldValue) -> {
                if (oldValue == null)
                    oldValue = new LinkedList<>();
                oldValue.offerLast(tweet);
                if (oldValue.size() > 10)
                    oldValue.removeFirst();
                return oldValue;
            });
            ts++;
        }

        public List<Integer> getNewsFeed(int userId) {
            PriorityQueue<Tweet> all = new PriorityQueue<>(40, (o1, o2) -> -Integer.compare(o1.ts, o2.ts));
            if (starTweetBox.get(userId) != null)
                all.addAll(starTweetBox.get(userId));
            if (fansToStar.containsKey(userId)) {
                for (Integer star : fansToStar.get(userId)) {
                    if (starTweetBox.get(star) != null)
                        all.addAll(starTweetBox.get(star));
                }
            }
            ArrayList<Integer> result = new ArrayList<>(10);
            for (int i = 0; i < 10 && all.size() > 0; i++) {
                result.add(all.poll().tweetId);
            }
            return result;
        }

        public void follow(int fans, int star) {
            if (fans == star) return;
            fansToStar.compute(fans, (key, oldValue) -> {
                if (oldValue == null) oldValue = new HashSet<>();
                oldValue.add(star);
                return oldValue;
            });
        }

        public void unfollow(int fans, int star) {
            if (fans == star) return;
            if (fansToStar.get(fans) != null)
                fansToStar.get(fans).remove(star);
        }
    }

    public static void main(String[] args) {
        //["Twitter","postTweet","getNewsFeed","follow","postTweet","getNewsFeed","unfollow","getNewsFeed"]
        //[[],[1,9],[1],[1,2],[2,6],[1],[1,2],[1]]

        //["Twitter","postTweet","getNewsFeed","follow","postTweet","getNewsFeed","unfollow","getNewsFeed"]
        //[[],[1,5],[1],[1,2],[2,6],[1],[1,2],[1]]

        //["Twitter","postTweet","follow","getNewsFeed"]
        //[[],[1,5],[1,1],[1]]

        //["Twitter","postTweet","postTweet","unfollow","getNewsFeed"]
        //[[],[1,4],[2,5],[1,2],[1]]
        System.out.println(new LC355_2());
    }
}
